/**
 * This software was produced for the U. S. Government
 * under Contract No. FA8721-09-C-0002, and is
 * subject to the Rights in Noncommercial Computer Software
 * and Noncommercial Computer Software Documentation Clause
 * (DFARS) 252.227-7014 (JUN 1995)
 * 
 * (c) 2009 The MITRE Corporation. All Rights Reserved.
 *
 * SPMIF to OPNET Translator
 * Author: ewalters
 * Created: 3:34:55 PM, Aug 13, 2007
 * MITRE Corporation
 */
package com.mitre.spmif2opnet.generation.ir;

import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;

import com.mitre.spmif2opnet.generation.OpnetGraphConverter;
import com.mitre.spmif2opnet.opnet.network.Attr;

/**
 * Abstract representation of OPNET Tasks
 */
public class Task {
	/**
	 * Task name
	 */
	private String _name;
	/** 
	 * Task Phases
	 */
	private List<Phase> _phases;
	/**
	 * Interarrival time for the task
	 */
	private double _inter_arrival;
	/**
	 * Source device name
	 */
	private String _source;
	// NOTE: Other possible info
	// - Connection Policy
	// - Ace Defaults
	
	/**
	 * Default constructor
	 * @param name task name
	 * @param inter_time arrival time
	 */
	public Task(String name, double inter_time) {
		_name = name;	
		_phases = new LinkedList<Phase>();
		_inter_arrival = inter_time;
		_source = null;
	}

	/**
	 * Add a phase to the task
	 * @param p the phase
	 */
	public void addPhase(Phase p) {
		_phases.add(p);
	}
	
	/**
	 * Set the task source
	 * @param source the source
	 */
	public void setSource(String source) {
		_source = source;
	}
	
	/**
	 * Unique task identifier
	 */
	private static int _task_id = 0;
	
	/**
	 * Get a unique task name
	 * @return the name
	 */
	public static String getNewTaskName() {
		String task_name = "task" + Integer.toString(_task_id);
		++_task_id;
		return task_name;
	}

	/**
	 * Turn the task into XML attributes
	 * @param prefix attribute prefix
	 * @return list of XML attributes
	 */
	public List<Attr> getAttributes(String prefix) {
		List<Attr> attrs = new LinkedList<Attr>();
		attrs.add(OpnetGraphConverter.makeAttr(prefix + "Manual Configuration.count",
				Integer.toString(_phases.size())));
		attrs.add(OpnetGraphConverter.makeAttr(prefix + "Task Name", _name));
		int i = 0;
		Hashtable<String, Double> total_times = new Hashtable<String, Double>();
		for (Phase p : _phases) {
			if (p.isProcessingPhase()) {
				Endpoint end = p.getSource();
				if (end != null) {
					Double total_time = total_times.get(end.getName());
					if (total_time == null) {
						total_time = 0.0;
					}
					total_time += end.getInitTime();
					total_times.put(end.getName(), total_time);
				}
			}
			String p_prefix = prefix + "Manual Configuration [" + i + "].";
			attrs.addAll(p.getAttributes(p_prefix));
			++i;
		}
		// First order check for zero threads
		for (String endname : total_times.keySet()) {
			Double total_time = total_times.get(endname);
			if (total_time == 0.0) {
				System.out.println("[WARNING] Zero time detected for all phases of task " + this.getName()
						+ " on device " + endname);
			}
		}
		return attrs;
	}
	
	/**
	 * Name accessor
	 * @return the name
	 */
	public String getName() {
		return _name;
	}
	
	/**
	 * Arrival time accessor
	 * @return the time
	 */
	public double getInterarrivalTime() {
		return _inter_arrival;
	}
	
	/**
	 * Source accessor
	 * @return the source
	 */
	public String getSource() {
		return _source;
	}
}
